package com.lf.mykotlin.property

/**
 * @date: 2023/4/27
 *
 * 可空类型 安全判断
 */
class MyKotlinNullProperty {

    /*
        1. 定义一个不可为空的变量，
            用var修饰的变量可以被重新赋值，
            用val修饰的变量则不能，但是不能赋值为null
     */
    var a : Int = 12
    val b : Int = 13


    /*
        2. 定义一个可为空类型的变量，  即变量可以被赋值为null
            定义格式为：修饰符 变量名 ： 类型? = 值
    */
    var nullA : Int? = 12
    val nullB : Int? = 13


    /*
        3. 使用符号?.判断
            该符号的用法为：可空类型变量?.属性/方法。如果可空类型变量为null时，返回null
            这种用法大量用于链式操作的用法中，能有效避免空引用异常（NullPointException），
            因为只要链式其中的一个为null，则整个表达式都为null
     */
    fun testLian() {
        var str : String? = "123456"
        str = null

        println(str?.length)   // 当变量str为null时，会返回空(null)
    }


    /*
        4. 函数中使用可空类型的情况下
            当一个函数/方法有返回值时，如果方法中的代码使用?.去返回一个值，那么方法的返回值的类型后面也要加上?符号
     */
    fun funNullMethod() : Int? {
        val str : String? = "123456"
        return str?.length
    }


    /*
        5. !!操作符
           !!操作符可谓是给爱好空引用异常（NullPointException）的开发者使用，
           因为在使用一个可空类型变量时，在该变量后面加上!!操作符，会显示的抛出NullPointException异常
     */
    fun test11() {
        val testStr : String? = null
        println(testStr!!.length)
    }

    /*
        6. as?操作符
            其实这里是指as操作符，表示类型转换，如果不能正常转换的情况下使用as?操作符。
            当使用as操作符的使用不能正常的转换的情况下会抛出类型转换（ClassCastException）异常，
            而使用as?操作符则会返回null,但是不会抛出异常
     */
    fun testAs() {
        val num2 : Int? = "Koltin" as? Int
        println("nun2 = $num2") // 输出 null
    }

    fun testProperty() {

        a = 20
        // a = null 不能赋值为null
        // b = 20   不能被重新赋值


        if(a == null) {
            // 这样的判断毫无意义，因为变量a永远不可能null
        }


        // 可以赋值
        nullA = null

        // 可以判断
        if(nullA == null){
            println("nullA = $nullA")
        }
    }

}